package com.custom.action.core;

import com.custom.comm.page.DbPageRows;
import com.custom.jdbc.configuration.DbDataSource;
import com.custom.jdbc.configuration.DbGlobalConfig;
import com.custom.jdbc.interfaces.TransactionExecutor;
import com.custom.jdbc.session.JdbcSqlSessionFactory;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 最终对外的JDBC基础操作对象
 * <br/> 该对象只有最基础的原始SQL操作方法，若需要条件构造器可以配合{@link JdbcDao}一起使用
 * @see JdbcDao
 * @author   Xiao-Bai
 * @since  2022/4/17 21:31
 */
public class JdbcOpDao extends BaseOpHandler {


    /* ----------------------------------------------------------------select---------------------------------------------------------------- */

    /**
     * 根据条件查询多条记录: 例（and a.name = ?）
     */
    public <T> List<T> selectList(Class<T> t, String condition, Object... params) throws Exception {
        return sqlExecutor.selectList(t, condition, params);
    }

    /**
     * 根据多个主键查询多条记录
     */
    public <T> List<T> selectBatchKeys(Class<T> t, Collection<? extends Serializable> keys) throws Exception {
        return sqlExecutor.selectBatchKeys(t, keys);
    }

    /**
     * 根据sql查询多条记录: 例（select * from table ）
     */
    public <T> List<T> selectListBySql(Class<T> t, String sql, Object... params) throws Exception {
        return sqlExecutor.selectListBySql(t, sql, params);
    }

    /**
     * 根据条件进行分页查询: 例（and a.name = ?）
     */
    public <T> DbPageRows<T> selectPage(Class<T> t, String condition, DbPageRows<T> dbPageRows, Object... params) throws Exception {
        return sqlExecutor.selectPage(t, condition, dbPageRows, params);
    }

    /**
     * 根据主键查询一条记录
     */
    public <T> T selectByKey(Class<T> t, Serializable key) throws Exception {
        return sqlExecutor.selectByKey(t, key);
    }

    /**
     * 纯sql查询一条记录
     */
    public <T> T selectOneBySql(Class<T> t, String sql, Object... params) throws Exception {
        return sqlExecutor.selectOneBySql(t, sql, params);
    }

    /**
     * 纯sql查询单个值
     */
    public Object selectObjBySql(String sql, Object... params) throws Exception {
        return sqlExecutor.selectObjBySql(sql, params);
    }

    /**
     * 查询多条单次映射关系
     * <br/> 可用于一些聚合查询后的结果映射
     * 1.例如: 查询每个名字的使用数量 结果如下
     * <tr>
     *     <th>name</th>
     *     <th>count</th>
     * </tr>
     * <tr>
     *     <td>zhangsan</td>
     *     <td>999</td>
     * </tr>
     * <tr>
     *     <td>lisi</td>
     *     <td>888</td>
     * </tr>
     * <br/> key即为<b>[zhangsan]</b>, value为<b>[999]</b>
     *
     * <br/><p></p>
     * 2.例如: 查询每个班的平均分
     * <tr>
     *     <th>class</th>
     *     <th>avgScore</th>
     * </tr>
     * <tr>
     *     <td>c01</td>
     *     <td>78.5</td>
     * </tr>
     * <tr>
     *     <td>c02</td>
     *     <td>86.5</td>
     * </tr>
     * <br/> key即为<b>[c01]</b>, value为<b>[78.5]</b>
     * <p></p>
     * @param kClass key的类型
     * @param vClass value的类型
     * @param sql 执行的sql
     * @param params 参数
     */
    public <K, V> Map<K, V> selectMap(Class<K> kClass, Class<V> vClass, String sql, Object... params) throws Exception {
        return sqlExecutor.selectMap(kClass, vClass, sql, params);
    }


    /**
     * 根据条件查询一条记录
     * @param condition and a.name = ?
     * @param params "zhangsan"
     */
    public <T> T selectOne(Class<T> t, String condition, Object... params) throws Exception {
        return sqlExecutor.selectOne(t, condition, params);
    }

    /**
     * 查询数组（t只支持基础类型对应的引用类型）
     * <p>
     *  额外支持
     *  {@link java.lang.String}
     *  {@link java.math.BigDecimal}
     *  {@link java.util.Date}
     * </p>
     */
    public <T> T[] selectArrays(Class<T> t, String sql, Object... params) throws Exception {
        return sqlExecutor.selectArrays(t, sql, params);
    }

    /* ----------------------------------------------------------------delete---------------------------------------------------------------- */

    /**
     * 根据主键删除一条记录
     */
    public <T> int deleteByKey(Class<T> t, Serializable key) throws Exception {
        return sqlExecutor.deleteByKey(t, key);
    }

    /**
     * 根据主键删除多条记录
     */
    public <T> int deleteBatchKeys(Class<T> t, Collection<? extends Serializable> keys) throws Exception {
        return sqlExecutor.deleteBatchKeys(t, keys);
    }

    /**
     * 根据条件删除记录
     */
    public <T> int deleteByCondition(Class<T> t, String condition, Object... params) throws Exception {
        return sqlExecutor.deleteByCondition(t, condition, params);
    }


    /* ----------------------------------------------------------------insert---------------------------------------------------------------- */

    /**
     * 插入一条记录(默认在实体中set新的主键)
     */
    public <T> long insert(T entity) throws Exception {
        return sqlExecutor.insert(entity);
    }

    /**
     * 插入多条记录(默认在实体中set新的主键)
     */
    public <T> int insertBatch(List<T> entityList) throws Exception {
        return sqlExecutor.insertBatch(entityList);
    }


    /* ----------------------------------------------------------------update---------------------------------------------------------------- */

    /**
     * 根据主键修改一条记录
     */
    public <T> int updateByKey(T entity) throws Exception {
        return sqlExecutor.updateByKey(entity);
    }

    /**
     * 根据条件修改一条记录
     */
    public <T> int updateByCondition(T entity, String condition, Object... params) throws Exception {
        return sqlExecutor.updateByCondition(entity, condition, params);
    }


    /* ----------------------------------------------------------------common---------------------------------------------------------------- */

    /**
     * 保存一条记录（根据主键添加或修改）
     */
    public <T> int save(T entity) throws Exception {
        return sqlExecutor.save(entity);
    }

    /**
     * 执行一条sql（增删改）
     */
    public <T> int executeSql(String sql, Object... params) throws Exception {
        return sqlExecutor.executeSql(sql, params);
    }

    /**
     * 执行事务
     */
    public void execTrans(TransactionExecutor executor) throws Exception {
        sqlExecutor.execTrans(executor);
    }


    public JdbcOpDao(DbDataSource dbDataSource, DbGlobalConfig globalConfig) {
        super(dbDataSource, globalConfig);
    }

    public JdbcOpDao(JdbcSqlSessionFactory sqlSessionFactory) {
        super(sqlSessionFactory);
    }

}
